package com.danbay.cloud.device.service;

import com.danbay.cloud.base.constants.DeviceType;
import com.danbay.cloud.device.constant.DeviceCommonConstant;
import com.danbay.cloud.device.dto.DeviceOfflineDto;
import com.danbay.cloud.device.dto.DeviceOfflineListDto;
import com.danbay.cloud.device.dto.HouseInfoDto;
import com.danbay.cloud.device.entity.CenterControl;
import com.danbay.cloud.device.entity.DeviceInfo;
import com.danbay.cloud.device.entity.EnergyDevice;
import com.danbay.cloud.device.mapper.CenterControlMapper;
import com.danbay.cloud.device.mapper.DeviceInfoMapper;
import com.danbay.cloud.device.mapper.EnergyDeviceMapper;
import com.danbay.framework.utils.ArrayUtils;
import com.danbay.framework.utils.DateUtils;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yangyanchen on 2018/1/10
 *         Copyright © 2016 －2017 旦倍科技
 */
@Service
public class DeviceOfflineService {

    private String EMPTY_STRING = "";

    private String DEVICE_CENTER_CONTROL_VIEW = "中控";

    private String DEVICE_LOCK_VIEW = "门锁";

    private String DEVICE_EM_METER = "电表";

    private String DEVICE_WM_METER = "水表";

    private String ONLINE_VIEW = "在线";

    private String OFFLINE_VIEW = "离线";

    @Autowired
    private CenterControlMapper centerControlMapper;

    @Autowired
    private DeviceCacheService deviceCacheService;

    @Autowired
    private DeviceInfoMapper deviceInfoMapper;

    @Autowired
    private EnergyDeviceMapper energyDeviceMapper;

    /**
     * 缓存中控离线数据:
     *  待优化部分,是否有房间关联
     * @param centerControl
     */
    public void cacheCenterControlState(CenterControl centerControl,boolean isLogin){
        DeviceOfflineListDto deviceOfflineListDto = deviceCacheService.getDeviceOfflineList(DeviceCommonConstant.DEVICE_OFF_LINE_KEY);
        //去重
        List<DeviceOfflineDto> list = clearByDeviceId(centerControl.getDeviceId(),deviceOfflineListDto);
        if (!isLogin){
            //加上一重条件,不带房间的id信息
            HouseInfoDto houseInfoDto = centerControlMapper.findHouseInfoById(centerControl);
            if (null != houseInfoDto){
                //中控绑定了房间才做数据缓存
                DeviceOfflineDto deviceOfflineDto = DeviceOfflineDto.builder()
                        .homeAddress(houseInfoDto.getHomeAddress())
                        .homeNo(houseInfoDto.getHouseNum()==null?EMPTY_STRING:houseInfoDto.getHouseNum())
                        .macAddress(centerControl.getMacAddress())
                        .deviceId(centerControl.getDeviceId())
                        .lastActiveTime(DateUtils.now(DateUtils.YMDHMS1))
                        .deviceType(DEVICE_CENTER_CONTROL_VIEW)
                        .fatherDeviceId(EMPTY_STRING)
                        .fatherMacAddress(EMPTY_STRING)
                        .fatherOnlineState(EMPTY_STRING).build();
                if (ArrayUtils.isNullOrEmpty(list)){
                    list = Lists.newLinkedList();
                }
                list.add(deviceOfflineDto);
                //这里再添加一层缓存,设备遇到这层缓存直接跳过.
                deviceOfflineListDto.setDeviceOfflineDtoList(list);
            }
        }
        deviceCacheService.setDeviceOfflineList(DeviceCommonConstant.DEVICE_OFF_LINE_KEY, deviceOfflineListDto);
    }

    public void cacheLockState(DeviceInfo lockInfo,boolean isLogin){
        DeviceOfflineListDto deviceOfflineListDto = deviceCacheService.getDeviceOfflineList(DeviceCommonConstant.DEVICE_OFF_LINE_KEY);
        //忽略数据为空,但是要去重
        List<DeviceOfflineDto> list = clearByDeviceId(lockInfo.getDeviceId(),deviceOfflineListDto);
        if (!isLogin){
            DeviceOfflineDto deviceOfflineDto = deviceInfoMapper.findOfflineDeviceByDeviceId(lockInfo);
            if (null != deviceOfflineDto ){
                if (deviceCacheService.isDeviceOnline(deviceOfflineDto.getFatherDeviceId())){
                    deviceOfflineDto.setDeviceType(DEVICE_LOCK_VIEW);
                    deviceOfflineDto.setLastActiveTime(DateUtils.now(DateUtils.YMDHMS1));
                    deviceOfflineDto.setFatherOnlineState(isFatherDeviceOnline(deviceOfflineDto.getFatherDeviceId()));
                    if (ArrayUtils.isNullOrEmpty(list)){
                        list = Lists.newLinkedList();
                    }
                    list.add(deviceOfflineDto);
                }
            }
        }
        deviceOfflineListDto.setDeviceOfflineDtoList(list);
        deviceCacheService.setDeviceOfflineList(DeviceCommonConstant.DEVICE_OFF_LINE_KEY, deviceOfflineListDto);
    }

    public void cacheMeterState(EnergyDevice energyDevice,boolean isLogin,int deviceType){
        DeviceOfflineListDto deviceOfflineListDto = deviceCacheService.getDeviceOfflineList(DeviceCommonConstant.DEVICE_OFF_LINE_KEY);
        List<DeviceOfflineDto> list = clearByDeviceId(energyDevice.getDeviceId(),deviceOfflineListDto);
        if (!isLogin){
            DeviceOfflineDto deviceOfflineDto = energyDeviceMapper.findOfflineDeviceByDeviceId(energyDevice);
            if (null != deviceOfflineDto ){
               if (deviceCacheService.isDeviceOnline(deviceOfflineDto.getFatherDeviceId())){
                   energyDevice.setDeviceType(deviceType == DeviceType.EM_METER.value()?DEVICE_EM_METER:DEVICE_WM_METER);
                   deviceOfflineDto.setLastActiveTime(DateUtils.now(DateUtils.YMDHMS1));
                   deviceOfflineDto.setFatherOnlineState(isFatherDeviceOnline(deviceOfflineDto.getFatherDeviceId()));
               }
                list.add(deviceOfflineDto);
            }
        }
        deviceOfflineListDto.setDeviceOfflineDtoList(list);
        deviceCacheService.setDeviceOfflineList(DeviceCommonConstant.DEVICE_OFF_LINE_KEY, deviceOfflineListDto);

    }

    private List<DeviceOfflineDto> clearByDeviceId(String deviceId,DeviceOfflineListDto deviceOfflineListDto){
        //判断数据是否为空
        if (null != deviceOfflineListDto){
            if (!ArrayUtils.isNullOrEmpty(deviceOfflineListDto.getDeviceOfflineDtoList())){
                return deviceOfflineListDto.getDeviceOfflineDtoList().stream().filter(
                        ArrayUtils.distinctByKey(offlineDto ->
                                deviceId.equalsIgnoreCase(
                                        offlineDto.getDeviceId()))).collect(Collectors.toList());
            }
        }
        return null;
    }

    private String isFatherDeviceOnline(String deviceId){
        return deviceCacheService.isDeviceOnline(deviceId)?ONLINE_VIEW: OFFLINE_VIEW;
    }

}
